from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


class UserProfile(models.Model):
    """用户配置文件扩展模型"""
    THEME_CHOICES = [
        ('light', '浅色主题'),
        ('dark', '深色主题'),
        ('auto', '自动切换'),
    ]
    
    LANGUAGE_CHOICES = [
        ('zh-hans', '简体中文'),
        ('zh-hant', '繁体中文'),
        ('en', 'English'),
    ]

    user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name="用户")
    avatar = models.ImageField(upload_to='avatars/', blank=True, null=True, verbose_name="头像")
    phone = models.CharField(max_length=20, blank=True, verbose_name="手机号码")
    address = models.TextField(blank=True, verbose_name="地址")
    theme = models.CharField(max_length=10, choices=THEME_CHOICES, default='light', verbose_name="主题设置")
    language = models.CharField(max_length=10, choices=LANGUAGE_CHOICES, default='zh-hans', verbose_name="语言设置")
    timezone = models.CharField(max_length=50, default='Asia/Shanghai', verbose_name="时区")
    email_notifications = models.BooleanField(default=True, verbose_name="邮件通知")
    push_notifications = models.BooleanField(default=True, verbose_name="推送通知")
    device_alerts = models.BooleanField(default=True, verbose_name="设备告警")
    scene_notifications = models.BooleanField(default=True, verbose_name="场景通知")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "用户配置"
        verbose_name_plural = "用户配置"

    def __str__(self):
        return f"{self.user.username}的配置"

    @property
    def display_name(self):
        """获取显示名称"""
        return self.user.get_full_name() or self.user.username

    def get_device_count(self):
        """获取用户设备数量"""
        from apps.devices.models import Device
        return Device.objects.filter(owner=self.user, is_active=True).count()

    def get_scene_count(self):
        """获取用户场景数量"""
        from apps.scenes.models import Scene
        return Scene.objects.filter(owner=self.user, is_active=True).count()


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    """用户创建时自动创建配置文件"""
    if created:
        UserProfile.objects.create(user=instance)


@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    """保存用户时同时保存配置文件"""
    if hasattr(instance, 'userprofile'):
        instance.userprofile.save()


class UserActivity(models.Model):
    """用户活动记录模型"""
    ACTIVITY_TYPE_CHOICES = [
        ('login', '登录'),
        ('logout', '登出'),
        ('device_control', '设备控制'),
        ('scene_execute', '场景执行'),
        ('settings_change', '设置修改'),
        ('credential_add', '添加凭证'),
        ('credential_update', '更新凭证'),
    ]

    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户")
    activity_type = models.CharField(max_length=20, choices=ACTIVITY_TYPE_CHOICES, verbose_name="活动类型")
    description = models.CharField(max_length=200, verbose_name="活动描述")
    ip_address = models.GenericIPAddressField(blank=True, null=True, verbose_name="IP地址")
    user_agent = models.TextField(blank=True, verbose_name="用户代理")
    extra_data = models.JSONField(default=dict, verbose_name="额外数据")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "用户活动"
        verbose_name_plural = "用户活动"
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.user.username} - {self.get_activity_type_display()} ({self.created_at.strftime('%Y-%m-%d %H:%M')})"

    @classmethod
    def log_activity(cls, user, activity_type, description, request=None, extra_data=None):
        """记录用户活动"""
        activity = cls(
            user=user,
            activity_type=activity_type,
            description=description,
            extra_data=extra_data or {}
        )
        
        if request:
            activity.ip_address = cls.get_client_ip(request)
            activity.user_agent = request.META.get('HTTP_USER_AGENT', '')
        
        activity.save()
        return activity

    @staticmethod
    def get_client_ip(request):
        """获取客户端IP地址"""
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip


class UserPreference(models.Model):
    """用户偏好设置模型"""
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户")
    key = models.CharField(max_length=100, verbose_name="设置键")
    value = models.TextField(verbose_name="设置值")
    value_type = models.CharField(max_length=20, default='string', verbose_name="值类型")
    description = models.CharField(max_length=200, blank=True, verbose_name="设置描述")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "用户偏好"
        verbose_name_plural = "用户偏好"
        unique_together = ['user', 'key']

    def __str__(self):
        return f"{self.user.username} - {self.key}"

    def get_typed_value(self):
        """根据类型返回对应的值"""
        if self.value_type == 'boolean':
            return self.value.lower() in ('true', '1', 'yes')
        elif self.value_type == 'integer':
            try:
                return int(self.value)
            except ValueError:
                return 0
        elif self.value_type == 'float':
            try:
                return float(self.value)
            except ValueError:
                return 0.0
        elif self.value_type == 'json':
            import json
            try:
                return json.loads(self.value)
            except json.JSONDecodeError:
                return {}
        else:
            return self.value

    @classmethod
    def set_preference(cls, user, key, value, value_type='string', description=''):
        """设置用户偏好"""
        preference, created = cls.objects.get_or_create(
            user=user,
            key=key,
            defaults={
                'value': str(value),
                'value_type': value_type,
                'description': description
            }
        )
        
        if not created:
            preference.value = str(value)
            preference.value_type = value_type
            if description:
                preference.description = description
            preference.save()
        
        return preference

    @classmethod
    def get_preference(cls, user, key, default=None):
        """获取用户偏好"""
        try:
            preference = cls.objects.get(user=user, key=key)
            return preference.get_typed_value()
        except cls.DoesNotExist:
            return default
